package com.molichuxing.gateway.bff.order.services.impl;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.dto.TabDto;
import com.molichuxing.framework.utils.ObjectCastUtil;
import com.molichuxing.gateway.bff.order.convertor.Convert;
import com.molichuxing.gateway.bff.order.entity.request.create.OrderRecycleCarsCreateVo;
import com.molichuxing.gateway.bff.order.entity.request.create.OrderRenegeCreateVo;
import com.molichuxing.gateway.bff.order.entity.request.modify.OrderRenegeCancelModifyVo;
import com.molichuxing.gateway.bff.order.entity.request.modify.OrderRenegeCompleteModifyVo;
import com.molichuxing.gateway.bff.order.entity.request.modify.OrderRenegeCostModifyVo;
import com.molichuxing.gateway.bff.order.entity.response.OrderNegotiateRenegeVo;
import com.molichuxing.gateway.bff.order.entity.response.OrderRenegeVo;
import com.molichuxing.gateway.bff.order.services.OrderRenegeBffService;
import com.molichuxing.services.business.dto.request.create.OrderRenegeCreateBizDto;
import com.molichuxing.services.business.dto.request.modify.OrderRenegeCancelModifyBizDto;
import com.molichuxing.services.business.dto.request.modify.OrderRenegeCompleteModifyBizDto;
import com.molichuxing.services.business.dto.request.modify.OrderRenegeCostModifyBizDto;
import com.molichuxing.services.business.dto.request.modify.StockCarBizModifyDto;
import com.molichuxing.services.business.dto.response.OrderRenegeBizDto;
import com.molichuxing.services.business.service.OrderRenegeBizService;
import com.molichuxing.services.business.service.StockCarBizService;
import com.molichuxing.services.infrastructure.dto.response.OrderExclusivelDto;
import com.molichuxing.services.infrastructure.dto.response.OrderNegotiateRenegeDto;
import com.molichuxing.services.infrastructure.dto.response.PaymentDto;
import com.molichuxing.services.infrastructure.dto.response.UserDto;
import com.molichuxing.services.infrastructure.service.*;
import com.molichuxing.services.property.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


@Service("orderRenegeBffService")
public class OrderRenegeBffServiceImpl implements OrderRenegeBffService {
    private static final Logger logger = LoggerFactory.getLogger(OrderBffServiceImpl.class);

    @Resource
    private OrderRenegeBizService orderRenegeBizService;

    @Resource
    private ContractService contractService;

    @Resource
    private UserService userService;

    @Resource
    private PaymentService paymentService;

    @Resource
    private OrderScheduleService orderScheduleService;

    @Resource
    private OrderRenegeService orderRenegeService;

    @Resource
    private OrderExclusivelService orderExclusivelService;

    @Resource
    private LawsuitService lawsuitService;

    @Resource
    private StockCarService stockCarService;

    @Resource
    private StockCarBizService stockCarBizService;

    @Resource
    private CarService carService;

    /**
     * 同意退租
     *
     * @param orderRenegeCreateVo
     * @return
     * @throws Exception
     */
    @Override
    public Boolean createRenege(OrderRenegeCreateVo orderRenegeCreateVo) throws Exception {
        OrderRenegeCreateBizDto orderRenegeCreateBizDto = Convert.toOrderRenegeCreateBizDto(orderRenegeCreateVo);
        return orderRenegeBizService.createRenege(orderRenegeCreateBizDto);
    }

    /**
     * 取消退租
     *
     * @param orderRenegeCancelModifyVo
     * @return
     * @throws Exception
     */
    @Override
    public Boolean modifyCancel(OrderRenegeCancelModifyVo orderRenegeCancelModifyVo) throws Exception {
        OrderRenegeCancelModifyBizDto orderRenegeCancelModifyBizDto = Convert.toOrderRenegeCancelModifyBizDto(orderRenegeCancelModifyVo);
        return orderRenegeBizService.modifyCancel(orderRenegeCancelModifyBizDto);
    }

    /**
     * 发起收/付款
     *
     * @param orderRenegeCostModifyVo
     * @return
     * @throws Exception
     */
    @Override
    public Boolean modifyCost(OrderRenegeCostModifyVo orderRenegeCostModifyVo) throws Exception {
        OrderRenegeCostModifyBizDto orderRenegeCostModifyBizDto = Convert.toOrderRenegeCostModifyBizDto(orderRenegeCostModifyVo);
        return orderRenegeBizService.modifyCost(orderRenegeCostModifyBizDto);
    }

    /**
     * 退款完成
     *
     * @param orderRenegeCompleteModifyVo
     * @return
     * @throws Exception
     */
    @Override
    public Boolean modifyComplete(OrderRenegeCompleteModifyVo orderRenegeCompleteModifyVo) throws Exception {
        OrderRenegeCompleteModifyBizDto orderRenegeCompleteModifyBizDto = Convert.toOrderRenegeCompleteModifyBizDto(orderRenegeCompleteModifyVo);
        if (!orderRenegeBizService.modifyComplete(orderRenegeCompleteModifyBizDto)) {
            return false;
        }
        // 修改合同-协商失效
        contractService.modifyStatusByOrderCode(orderRenegeCompleteModifyVo.getOrderCode(),
                ContractStatusEnum.NEGOTIATE_NONEFFECTIVE.getValue());
        // 解除协议修改为已终止
        try {
            contractService.modifyStatus(orderRenegeCompleteModifyVo.getOrderCode(),
                    ContractStatusEnum.TERMINATED, Arrays.asList(ContractTypeEnum.RESCISSION_CONTRACT));
        } catch (Exception e) {
            logger.error("解除协议状态修改为已终止异常", e);
        }

        return true;
    }

    /**
     * 查询退租信息
     *
     * @param orderCode
     * @param userId
     * @return
     */
    @Override
    public OrderRenegeVo getOrderRenege(Long orderCode, Integer userId) {
        OrderRenegeVo result = null;
        OrderRenegeBizDto orderRenege = orderRenegeBizService.getOrderRenege(orderCode, userId);
        if (orderRenege == null) {
            return result;
        }
        result = Convert.toOrderRenegeVo(orderRenege);
        // 判断退租类型
        if (OrderRenegeCostTypeEnum.INCOME.equals(orderRenege.getCostType())) {
            // 我司应收，查询用户姓名
            UserDto user = userService.getUser(userId);
            result.setPayee(user == null ? null : user.getRealName());
            if (OrderRenegeStatusEnum.COMPLETE.equals(orderRenege.getRenegeStatus())) {
                // 查询支付信息
                List<PaymentDto> paymentDtos = paymentService.getSuccessPayment(orderCode, PaymentCostTypeEnum.RENEGE);
                if (paymentDtos == null || paymentDtos.isEmpty()) {
                    result.setRenegeTime(null);
                } else {
                    result.setRenegeTime(paymentDtos.get(0).getPayTime());
                }
            } else {
                result.setRenegeTime(null);
            }
        }

        return result;
    }

    /**
     * 查询订单协商退租列表
     *
     * @param selectParams
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public Paged<OrderNegotiateRenegeVo> getNegotiateRenegeList(Map<String, Object> params,
                                                                Integer pageNum, Integer pageSize) throws Exception {
        Paged<OrderNegotiateRenegeVo> result = new Paged<>(new ArrayList<>(), 0, pageSize);
        // 查询tab页签数量
        result.setTab(getOverdueTab());
        // 判断查询条件是否有用户信息
        if (StringUtils.isNotBlank(ObjectCastUtil.castString(params.get("userRealName")))
                || StringUtils.isNotBlank(ObjectCastUtil.castString(params.get("userPhone")))) {
            // 查询用户ids
            List<Integer> userIdList = getUserIds(ObjectCastUtil.castString(params.get("userRealName")),
                    ObjectCastUtil.castString(params.get("userPhone")));
            if (userIdList == null || userIdList.size() <= 0) {
                // 用户不存在
                return result;
            }
            params.put("userIds", userIdList);
            params.remove("userRealName");
            params.remove("userPhone");
            logger.info("[getNegotiateRenegeList]分页获取订单协商退租列表userIds：" + userIdList);
        }

        Paged<OrderNegotiateRenegeDto> orderNegotiateRenegeDtos = orderRenegeBizService
                .getNegotiateRenegePaged(params, pageNum, pageSize);
        // 判断是否查询为空
        if (orderNegotiateRenegeDtos == null) {
            return result;
        } else if (orderNegotiateRenegeDtos.isEmpty()) {
            return result.setTotal(orderNegotiateRenegeDtos.getTotal());
        }

        result.setTotal(orderNegotiateRenegeDtos.getTotal());
        // 用户id集合
        List<Integer> userIds = new ArrayList<>();
        for (OrderNegotiateRenegeDto orderNegotiateRenegeDto : orderNegotiateRenegeDtos
                .getList()) {
            userIds.add(orderNegotiateRenegeDto.getUserId());
            result.getList().add(Convert.toOrderNegotiateRenegeVo(orderNegotiateRenegeDto));
        }
        // 查询用户
        Map<Integer, UserDto> userMap = userService.getUsers(userIds);

        for (OrderNegotiateRenegeVo vo : result.getList()) {
            // 用户
            UserDto userDto = userMap == null ? null
                    : userMap.isEmpty() ? null : userMap.get(vo.getUserId());
            // 用户手机号
            vo.setUserPhone(userDto == null ? null : userDto.getPhone());
            // 用户姓名
            vo.setUserName(userDto == null ? null : userDto.getRealName());
        }

        return result;
    }

    private List<TabDto> getOverdueTab() throws Exception {
        List<TabDto> tabs = new ArrayList<>();
        // 逾期未还数量
        tabs.add(new TabDto("逾期未还款", 1,
                orderScheduleService.getOverdueTotal(OrderTypeEnum.EXCLUSIVEL)));
        // 协商退租数量
        tabs.add(new TabDto("逾期协商退租", 2,
                orderRenegeService.getRenegeTotal(OrderRenegeTypeEnum.NEGOTIATE)));
        // 法务诉讼数量
        tabs.add(new TabDto("法务诉讼", 3, lawsuitService.getLawsuitTotal()));
        return tabs;
    }

    /**
     * 根据用户姓名和手机号查询用户ids
     *
     * @param userRealName 用户姓名
     * @param userPhone    用户手机号
     * @return
     */
    private List<Integer> getUserIds(String userRealName, String userPhone) {
        List<Integer> result = null;
        // 查询用信息
        List<UserDto> userDtoList = userService.getUserList(null, userRealName, userPhone);
        if (userDtoList == null || userDtoList.isEmpty()) {
            // 用户不存在
            return result;
        }
        result = new ArrayList<>();
        for (UserDto userDto : userDtoList) {
            result.add(userDto.getId());
        }

        return result;
    }

    /**
     * 确认收车
     *
     * @param createVo
     * @return
     */
    @Override
    public boolean createRecycleCars(OrderRecycleCarsCreateVo createVo) throws Exception {
        RecycleStateEnum recycleStateEnum = RecycleStateEnum.getEnum(createVo.getRecycleState());
        // 退租还车
        orderRenegeBizService.createRecycleCar(Convert.toRecycleCarsCreateBizDto(createVo));

        // 查询订单信息
        OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(createVo.getOrderCode());

        // 运营状态
        CarsOperateStatusEnum carsOperateStatusEnum = null;
        // 用途状态
        CarsUseTypeEnum carsUseTypeEnum = null;
        // 库存运营状态
        StockCarCarStatusEnum stockCarCarStatusEnum = null;

        if (RecycleStateEnum.FAIL.equals(recycleStateEnum)) {
            //  收车失败(运营状态：不可租，库存运营状态：不可租)
            carsOperateStatusEnum = CarsOperateStatusEnum.NOT_RENT;
            stockCarCarStatusEnum = StockCarCarStatusEnum.NOT_RENT;
        } else if (RecycleStateEnum.FINISH.equals(recycleStateEnum)) {
            // 已收车(运营状态：不可租，库存运营状态：不可租)
            carsOperateStatusEnum = CarsOperateStatusEnum.NOT_RENT;
            stockCarCarStatusEnum = StockCarCarStatusEnum.NOT_RENT;
            try {
                // 修改仓储信息
                StockCarBizModifyDto bizModifyDto = new StockCarBizModifyDto();
                bizModifyDto.setCarId(orderExclusivel.getCarId());
                bizModifyDto.setStockId(createVo.getStockId());
                bizModifyDto.setAccountId(createVo.getOperateId());
                bizModifyDto.setAccountAccount(createVo.getOperateName());

                stockCarBizService.modifyAdvanceStock(bizModifyDto);
            } catch (Exception e) {
                logger.error("[createRecycleCars]确认收车修改仓储信息失败：{}", createVo);
            }
        } else if (RecycleStateEnum.LOSE.equals(recycleStateEnum)) {
            // 已丢失(运营状态：不可租，用途状态：已丢失，库存运营状态：不可租)
            carsOperateStatusEnum = CarsOperateStatusEnum.NOT_RENT;
            carsUseTypeEnum = CarsUseTypeEnum.WAS_LOST;
            stockCarCarStatusEnum = StockCarCarStatusEnum.NOT_RENT;

        } else if (RecycleStateEnum.SCRAP.equals(recycleStateEnum)) {
            // 已报废(运营状态：不可租，用途状态：已报废，库存运营状态：不可租)
            carsOperateStatusEnum = CarsOperateStatusEnum.NOT_RENT;
            carsUseTypeEnum = CarsUseTypeEnum.ABANDONED_VEHICLE;
            stockCarCarStatusEnum = StockCarCarStatusEnum.NOT_RENT;
        } else if (RecycleStateEnum.SALE.equals(recycleStateEnum)) {
            // 已售出(运营状态：已售出，用途状态：已售出，库存运营状态：已售出)
            carsOperateStatusEnum = CarsOperateStatusEnum.ALREADY_SOLD;
            carsUseTypeEnum = CarsUseTypeEnum.ALREADY_SOLD;
            stockCarCarStatusEnum = StockCarCarStatusEnum.RENTED;
        }

        try {
            // 修改车辆状态
            carService.modifyUseType(orderExclusivel.getCarId(),
                    carsOperateStatusEnum == null ? null : carsOperateStatusEnum.getValue(),
                    carsUseTypeEnum == null ? null : carsUseTypeEnum.getValue());
        } catch (Exception e) {
            logger.error("[createRecycleCars]确认收车修改车辆状态失败：{}", createVo);
        }
        try {
            // 修改运营状态
            if (stockCarCarStatusEnum != null) {
                stockCarService.modifyCarStatus(orderExclusivel.getCarId(),
                        stockCarCarStatusEnum.getValue());
            }

        } catch (Exception e) {
            logger.error("[createRecycleCars]确认收车修改运营状态失败：{}", createVo);
        }

        return false;
    }


    /**
     * 退租订单退租完成
     *
     * @param modifyVo
     * @return
     */
    @Override
    public boolean modifyRenegeFinish(OrderRenegeCompleteModifyVo modifyVo) {
        if (!orderRenegeBizService.modifyFinish(Convert.toOrderRenegeCompleteModifyBizDto(modifyVo))) {
            return false;
        }
        // 修改合同-协商失效
        contractService.modifyStatusByOrderCode(modifyVo.getOrderCode(),
                ContractStatusEnum.NEGOTIATE_NONEFFECTIVE.getValue());
        // 解除协议修改为已终止
        try {
            contractService.modifyStatus(modifyVo.getOrderCode(),
                    ContractStatusEnum.TERMINATED, Arrays.asList(ContractTypeEnum.RESCISSION_CONTRACT));
        } catch (Exception e) {
            logger.error("解除协议状态修改为已终止异常", e);
        }

        return true;
    }


}
